/**
 * 
 */
package com.fyp.client.ptma;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.Set;

import org.apache.http.HttpResponse;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.NotificationManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.Window;
import android.widget.Toast;

import com.fyp.client.ptma.ApplicationDetailFragment.ApplicationDetailClickListener;
import com.fyp.client.ptma.ApplicationListFragment.ApplicationClickListener;
import com.fyp.client.ptma.model.Application;
import com.fyp.client.ptma.model.ApplicationVersion;
import com.fyp.client.ptma.model.Downloader;
import com.fyp.client.ptma.model.Installation;
import com.fyp.client.ptma.model.User;
import com.fyp.client.ptma.utils.Device;
import com.fyp.client.ptma.utils.Helper;
import com.fyp.client.ptma.utils.NetworkConnectivity;
import com.fyp.client.ptma.xml.XmlBuilder;

/**
 * @author yahya
 * 
 */

public class ApplicationsList extends FragmentActivity implements
		ApplicationClickListener, ApplicationDetailClickListener
{

	private static final int RESPONSE_DELETE_APP = 1000;
	private ApplicationVersion version;

	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		this.requestWindowFeature(Window.FEATURE_NO_TITLE);

		super.onCreate(savedInstanceState);
		setContentView(getContentView());

	}

	int getContentView()
	{
		// TODO Auto-generated method stub
		return R.layout.application_activity;
	}

	void initViewRefereces()
	{

	}

	@Override
	public void onListItemClick(Application application)
	{
		ApplicationDetailFragment fragment = (ApplicationDetailFragment) getSupportFragmentManager()
				.findFragmentById(R.id.detailFragment);
		if (fragment != null && fragment.isInLayout())
		{

			fragment.updateView(application);
		}

	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu)
	{
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.action_bar_refresh, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item)
	{
		switch (item.getItemId())
		{
		case R.id.action_refresh:
			ApplicationListFragment listFrag = (ApplicationListFragment) getSupportFragmentManager()
					.findFragmentById(R.id.listFragment);

			break;

		default:
			break;
		}

		return true;
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode,
			Intent intent)
	{
		if (requestCode == RESPONSE_DELETE_APP && resultCode == RESULT_OK)
		{

			installApplication();
		}

		super.onActivityResult(requestCode, resultCode, intent);
	}

	private void showAppUninstallConfirmationDialogue()
	{

		new DialogFragment()
		{
			@Override
			public Dialog onCreateDialog(Bundle savedInstanceState)
			{
				// Use the Builder class for convenient dialog construction
				AlertDialog.Builder builder = new AlertDialog.Builder(
						getActivity());
				builder.setMessage(
						"You have to uninstall previous version of application "
								+ version.getVersionPk().getApplication()
										.getApplicationName())
						.setPositiveButton("Uninstall",
								new DialogInterface.OnClickListener()
								{
									public void onClick(DialogInterface dialog,
											int id)
									{
										uninstallPreviousVersion(version
												.getVersionPk()
												.getApplication()
												.getNameSpace());
									}
								})
						.setNegativeButton("Cancel",
								new DialogInterface.OnClickListener()
								{
									public void onClick(DialogInterface dialog,
											int id)
									{
										dismiss();
									}
								});
				// Create the AlertDialog object and return it
				return builder.create();
			}
		}.show(getSupportFragmentManager(), "Uninstall");
	}

	private int ID = 10;

	private void downloadApk()
	{

	}

	private void uninstallPreviousVersion(String _package)
	{

		Uri packageURI = Uri.parse("package:" + _package);
		Intent uninstallIntent = new Intent(Intent.ACTION_DELETE, packageURI);
		startActivityForResult(uninstallIntent, RESPONSE_DELETE_APP);

	}

	private ApplicationDownloader appDownloader;

	@Override
	public void onApplicationVersionClickListener(ApplicationVersion version)
	{
		System.out.println("onApplicationVersionClickListener");

		appDownloader = new ApplicationDownloader();
		appDownloader.execute(new Object[]
		{ version });

	}

	@Override
	public void onApplicationVersionLogClickListener(ApplicationVersion version)
	{
		System.out.println("onApplicationVersionLogClickListener");
		CustomIntent intent = new CustomIntent(this, LogScreen.class);
		intent.putExtra("dataToCarry", version);
		startActivity(intent);

	}

	private void installApplication()
	{

		Intent intent = new Intent(Intent.ACTION_VIEW);

		intent.setDataAndType(
				Uri.fromFile(new File(version.getOutputFilePathForApk())),
				"application/vnd.android.package-archive");

		startActivity(intent);
		Installation object = new Installation();
		SharedPreferences pref = this.getSharedPreferences(
				Constants.SHARED_PREFERENCE, Context.MODE_PRIVATE);

		String myEmail = Helper.decrypt(pref.getString(
				Constants.PREF_KEY_MYEMAIL, null));

		String devEmail = Helper.decrypt(pref.getString(
				Constants.PREF_KEY_DEVEMAIL, null));

		object.getDownloader().getUser().setEmail(devEmail);
		object.getDownloader().setEmail(myEmail);
		object.getDownloader().setDeviceId(Device.getDeviceNumber(this));
		object.setAppVersion(version);

		Helper.notification = object;

	}

	private class ApplicationDownloader extends
			AsyncTask<Object, Integer, Integer>
	{
		private NotificationManager mNotifyManager;
		private NotificationCompat.Builder mBuilder;

		private String downloadText = "Download in progress ";

		@Override
		protected void onPreExecute()
		{
			mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

			mBuilder = new NotificationCompat.Builder(ApplicationsList.this);
			mBuilder.setContentTitle("Apk Download")

			.setContentText(downloadText + "0%")
					.setSmallIcon(R.drawable.arrow_mini_down).setOngoing(true);
		}

		@Override
		protected void onPostExecute(Integer result)
		{
			if (result == 1)
			{
				mBuilder.setContentText("Download complete").setOngoing(false)
						.setProgress(0, 0, false).setSmallIcon(R.drawable.tick);
				mNotifyManager.notify(ID, mBuilder.build());

				if (Device.isAppInstalled(ApplicationsList.this, version
						.getVersionPk().getApplication().getNameSpace())
						&& version.isUninstallPrevious())
				{
					showAppUninstallConfirmationDialogue();
				} else if (version.getOutputFilePathForApk() != null)
				{
					installApplication();
				}

			} else if (result == 0)
			{
				mBuilder.setContentText("Download failed").setOngoing(false)
						.setProgress(0, 0, false)
						.setSmallIcon(R.drawable.exclamation5);
				mNotifyManager.notify(ID, mBuilder.build());
			}
		}

		@Override
		protected void onProgressUpdate(Integer... values)
		{
			mBuilder.setProgress(100, values[0], false)
					.setContentText(
							new StringBuilder(downloadText).append(values[0])
									.append("%"))
					.setSmallIcon(R.drawable.arrow_mini_down).setOngoing(true);
			mNotifyManager.notify(0, mBuilder.build());
		}

		@Override
		protected Integer doInBackground(Object... params)
		{
			int count;
			try
			{

				String url = getString(R.string.WS_URL)
						+ getString(R.string.WS_GETAPK);

				version = (ApplicationVersion) params[0];

				// Shared Pref
				SharedPreferences pref = ApplicationsList.this
						.getSharedPreferences(Constants.SHARED_PREFERENCE,
								Context.MODE_PRIVATE);

				String myEmail = Helper.decrypt(pref.getString(
						Constants.PREF_KEY_MYEMAIL, ""));

				String devEmail = Helper.decrypt(pref.getString(
						Constants.PREF_KEY_DEVEMAIL, ""));

				Device.createDirIfNotExists(version.getOutputFolderPathForApk());
				// Downloader
				Downloader downloader = new Downloader();
				downloader.setDeviceId(Device
						.getDeviceNumber(ApplicationsList.this));
				downloader.setDeviceOs(Build.VERSION.RELEASE);
				downloader.setEmail(myEmail);
				User user = new User(devEmail);
				downloader.setUser(user);

				HttpResponse response = NetworkConnectivity
						.performPostOperation(url,
								XmlBuilder.getXmlForAuthetication(downloader));

				InputStream input = new BufferedInputStream(response
						.getEntity().getContent(), 8192);

				// Output stream to write file
				OutputStream output = new FileOutputStream(
						version.getOutputFilePathForApk());

				byte data[] = new byte[1024];
				long lenghtOfFile = response.getEntity().getContentLength();
				long total = 0;

				while ((count = input.read(data)) != -1)
				{

					total += count;
					// publishing the progress....
					// After this onProgressUpdate will be called
					publishProgress((int) ((total * 100) / lenghtOfFile));

					// writing data to file
					output.write(data, 0, count);
				}

				// flushing output
				output.flush();

				// closing streams
				output.close();
				input.close();

			} catch (Exception e)
			{
				Log.e("Error: ", e.getMessage());

				return 0;
			}

			return 1;
		}
	}

	private long firstPress;
	private long seccondPress;

	@Override
	public void onBackPressed()
	{

		if (firstPress == 0L)
		{
			firstPress = System.currentTimeMillis();

			Toast.makeText(this, "Press again to exit", Toast.LENGTH_LONG)
					.show();
			return;
		} else
		{
			seccondPress = System.currentTimeMillis();

		}
		if ((seccondPress - firstPress) <= 5000)
		{
			firstPress = 0;
			seccondPress = 0;

			this.finish();
			android.os.Process.killProcess(android.os.Process.myPid());

		} else
		{
			firstPress = 0;
			seccondPress = 0;

		}

	}

}
